package com.ucode.admin.cgms.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.ucode.admin.base.core.CurrentLoginUserService;
import com.ucode.cgms.service.CgmsCompanionOfflineOrderReportService;
import com.ucode.cgms.service.CgmsCompanionProductService;
import com.ucode.cgms.service.CgmsCompanionUserService;
import com.ucode.model.cgms.CgmsCompanionOfflineOrderReport;
import com.ucode.model.cgms.CgmsCompanionProduct;
import com.ucode.model.cgms.CgmsCompanionUser;
import com.ucode.model.cgms.convert.CgmsCompanionOfflineOrderReportConvert;
import com.ucode.model.cgms.enums.CgmsCompanionUserStatuzEnum;
import com.ucode.model.cgms.form.CgmsAuditForm;
import com.ucode.model.cgms.form.CgmsCompanionOfflineOrderReportForm;
import com.ucode.model.cgms.vo.CgmsCompanionOfflineOrderReportVO;
import com.ucode.tool.base.Paginator;
import com.ucode.tool.base.ResponseResult;
import com.ucode.tool.base.enums.CommonAuditStatusEnum;
import com.ucode.tool.base.enums.GlobalResultCodeEnum;
import com.ucode.tool.base.enums.UserTypeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.util.IdentifyUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 陪玩线下订单报备管理控制器
 */
@Tag(name = "管理后台 - 陪玩社区系统 - 陪玩线下订单报备")
@RestController
@RequestMapping("/cgms/companion-offline-order-report")
@Validated
public class CgmsCompanionOfflineOrderReportController {

    @Resource
    private CgmsCompanionOfflineOrderReportService cgmsCompanionOfflineOrderReportService;
    
    @Resource
    private CgmsCompanionUserService cgmsCompanionUserService;
    
    @Resource
    private CgmsCompanionProductService cgmsCompanionProductService;
    
    @Resource
    private CurrentLoginUserService currentLoginUserService;

    /**
     * 获取陪玩线下订单报备分页列表
     * 
     * @param title 订单标题
     * @param productId 商品ID
     * @param serviceUserId 服务人员ID
     * @param createTimeInterval 创建时间区间
     * @param pageNum 页码
     * @param pageSize 每页记录数
     * @return 陪玩线下订单报备分页数据
     */
    @GetMapping("/page-list")
    @Operation(summary = "获得陪玩线下订单报备分页列表")
    @PreAuthorize("@usfs.hasPermission('cgms:companion-offline-order-report:query')")
    public ResponseResult<Paginator<CgmsCompanionOfflineOrderReportVO>> pageList(
            @Schema(description = "订单标题") @RequestParam(value = "title", required = false) String title,
            @Schema(description = "商品ID") @RequestParam(value = "productId", required = false) Long productId,
            @Schema(description = "服务人员ID") @RequestParam(value = "serviceUserId", required = false) Long serviceUserId,
            @Schema(description = "创建时间区间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") 
            @RequestParam(value = "createTimeInterval", required = false) LocalDateTime[] createTimeInterval,
            @Schema(description = "页码", example="1") @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @Schema(description = "每页记录数", example="10") @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {

        Map<String, Object> condition = new HashMap<>();
        if (StrUtil.isNotBlank(title))
            condition.put("title", StrUtil.concat(true, "%", title, "%")); // 使用前后模糊匹配
        if (ArrayUtil.isNotEmpty(createTimeInterval) && createTimeInterval.length == 2) {
            condition.put("startTime", createTimeInterval[0]);
            condition.put("endTime", createTimeInterval[1]);
        }
        condition.put("productId", productId);
        condition.put("serviceUserId", serviceUserId);
        condition.put("deltag", false);

        Paginator<CgmsCompanionOfflineOrderReport> paginator = cgmsCompanionOfflineOrderReportService.queryPageForList(condition, pageSize, pageNum);
        return ResponseResult.success(pageList(paginator));
    }

    /**
     * 获取陪玩线下订单报备详情
     * 
     * @param id 报备ID
     * @return 报备详情
     */
    @GetMapping("/getById/{id}")
    @Parameter(description="报备ID", name = "id", required = true, in = ParameterIn.PATH, example = "1024")
    @Operation(summary = "获取陪玩线下订单报备详情")
    @PreAuthorize("@usfs.hasPermission('cgms:companion-offline-order-report:query')")
    public ResponseResult<CgmsCompanionOfflineOrderReportVO> getById(@PathVariable(name="id", required=true) Long id) {
        if (ObjUtil.isNull(id)) {
            throw new UcodeServiceException(GlobalResultCodeEnum.VALIDATE_FAILED);
        }
        
        CgmsCompanionOfflineOrderReport report = cgmsCompanionOfflineOrderReportService.validate(id);
        CgmsCompanionOfflineOrderReportVO reportVO = CgmsCompanionOfflineOrderReportConvert.INSTANCE.convert(report);
        
        // 填充关联信息
        enrichReportVO(reportVO);
        
        return ResponseResult.success(reportVO);
    }

    /**
     * 创建陪玩线下订单报备
     * 
     * @param form 报备表单
     * @return 操作结果
     */
    @PostMapping("/create")
    @Operation(summary = "创建陪玩线下订单报备")
    @PreAuthorize("@usfs.hasPermission('cgms:companion-offline-order-report:create')")
    public ResponseResult<Long> create(@Valid @RequestBody CgmsCompanionOfflineOrderReportForm form) {
        CgmsCompanionOfflineOrderReport report = CgmsCompanionOfflineOrderReportConvert.INSTANCE.convert(form);
        report.setId(IdentifyUtils.getDefaultSnowflakeId());
        report.setAuditStatuz(CommonAuditStatusEnum.SUBMIT_REVIEW.getCode());
        cgmsCompanionOfflineOrderReportService.insert(report);
        return ResponseResult.success(report.getId());
    }

    /**
     * 更新陪玩线下订单报备
     * 
     * @param id 报备ID
     * @param form 报备表单
     * @return 操作结果
     */
    @PostMapping("/update/{id}")
    @Operation(summary = "更新陪玩线下订单报备")
    @Parameter(description="报备ID", name = "id", required = true, in = ParameterIn.PATH, example = "1024")
    @PreAuthorize("@usfs.hasPermission('cgms:companion-offline-order-report:update')")
    public ResponseResult<Object> update(
            @PathVariable(name="id", required=true) Long id,
            @Valid @RequestBody CgmsCompanionOfflineOrderReportForm form) {
        
        if (ObjUtil.isNull(id)) {
            throw new UcodeServiceException(GlobalResultCodeEnum.VALIDATE_FAILED);
        }
        
        CgmsCompanionOfflineOrderReport report = cgmsCompanionOfflineOrderReportService.validate(id);
        CgmsCompanionOfflineOrderReportConvert.INSTANCE.update(form, report);
        
        cgmsCompanionOfflineOrderReportService.update(report);
        return ResponseResult.success();
    }

    /**
     * 审核陪玩线下订单报备
     * 
     * @param form 审核表单
     * @return 操作结果
     */
    @PostMapping("/audit")
    @Operation(summary = "审核")
    @PreAuthorize("@usfs.hasPermission('cgms:companion-offline-order-report:audit')")
    public ResponseResult<Object> audit(@Valid @RequestBody CgmsAuditForm form) {

        List<CgmsCompanionOfflineOrderReport> list = cgmsCompanionOfflineOrderReportService.selectByPrimaryKeys(form.getIds());
        if(CollUtil.isNotEmpty(list)) {
            for (CgmsCompanionOfflineOrderReport report : list) {
                CgmsCompanionOfflineOrderReport bean = new CgmsCompanionOfflineOrderReport();
                bean.setId(report.getId());
                bean.setAuditStatuz(form.getStatuz());
                bean.setProcessorId(currentLoginUserService.getCurrentUserId());
                bean.setProcessorType(UserTypeEnum.ADMIN.getCode());
                bean.setProcessTime(LocalDateTime.now());
                bean.setProcessRemark(form.getRemark());
                cgmsCompanionOfflineOrderReportService.update(bean);
            }
        }

        return ResponseResult.success();
    }

    /**
     * 转移陪玩线下订单报备到回收站
     * 
     * @param id 报备ID
     * @return 操作结果
     */
    @PostMapping("/logic-delete/{id}")
    @Operation(summary = "转移到回收站")
    @Parameter(description="报备ID", name = "id", required = true, in = ParameterIn.PATH, example = "1024")
    @PreAuthorize("@usfs.hasPermission('cgms:companion-offline-order-report:logic-delete')")
    public ResponseResult<Object> logicDelete(@PathVariable(name="id", required=true) Long id) {
        cgmsCompanionOfflineOrderReportService.validate(id);
        int i = cgmsCompanionOfflineOrderReportService.logicDelete(id);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    /**
     * 批量转移陪玩线下订单报备到回收站
     * 
     * @param ids 报备ID集合
     * @return 操作结果
     */
    @PostMapping("/batch-logic-delete")
    @Operation(summary = "批量转移到回收站")
    @PreAuthorize("@usfs.hasPermission('cgms:companion-offline-order-report:logic-delete')")
    public ResponseResult<Boolean> batchLogicDeletePrimaryKey(
            @Schema(description = "编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
            @NotEmpty(message = "编号集合为空")
            @Size(min = 1, max = 20, message = "编号集合数量为1-20条")
            @RequestParam(value = "ids", required = true) List<Long> ids) {

        int i = cgmsCompanionOfflineOrderReportService.batchLogicDelete(ids);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    /**
     * 处理报备分页数据，填充关联信息
     * 
     * @param paginator 报备分页数据
     * @return 填充关联信息后的报备分页数据
     */
    private Paginator<CgmsCompanionOfflineOrderReportVO> pageList(Paginator<CgmsCompanionOfflineOrderReport> paginator) {
        if (paginator == null || CollUtil.isEmpty(paginator.getList())) {
            return new Paginator<>();
        }
        Paginator<CgmsCompanionOfflineOrderReportVO> paginatorVO = CgmsCompanionOfflineOrderReportConvert.INSTANCE.convertPage(paginator);
        
        if (CollUtil.isNotEmpty(paginatorVO.getList())) {
            Set<Long> serviceUserIds = paginatorVO.getList().stream()
                    .filter(vo -> ObjUtil.isNotNull(vo.getServiceUserId()) && !ObjUtil.equals(vo.getServiceUserId(), 0L))
                    .map(CgmsCompanionOfflineOrderReportVO::getServiceUserId)
                    .collect(Collectors.toSet());
            
            Set<Long> productIds = paginatorVO.getList().stream()
                    .filter(vo -> ObjUtil.isNotNull(vo.getProductId()) && !ObjUtil.equals(vo.getProductId(), 0L))
                    .map(CgmsCompanionOfflineOrderReportVO::getProductId)
                    .collect(Collectors.toSet());
            
            // 批量查询
            Map<Long, CgmsCompanionUser> serviceUserMap = CollUtil.isEmpty(serviceUserIds) ? 
                    new HashMap<>() : cgmsCompanionUserService.getMap(serviceUserIds);
            
            Map<Long, CgmsCompanionProduct> productMap = CollUtil.isEmpty(productIds) ? 
                    new HashMap<>() : cgmsCompanionProductService.getMap(productIds);
            
            // 填充数据
            for (CgmsCompanionOfflineOrderReportVO vo : paginatorVO.getList()) {
                // 填充服务人员信息
                if (ObjUtil.isNotNull(vo.getServiceUserId())) {
                    CgmsCompanionUser serviceUser = serviceUserMap.get(vo.getServiceUserId());
                    if (ObjUtil.isNotNull(serviceUser)) {
                        vo.setServiceUserNickname(serviceUser.getNickName());
                        vo.setServiceUserAvatar(serviceUser.getAvatar());
                    }
                }
                
                // 填充商品信息
                if (ObjUtil.isNotNull(vo.getProductId())) {
                    CgmsCompanionProduct product = productMap.get(vo.getProductId());
                    if (ObjUtil.isNotNull(product)) {
                        vo.setProductName(product.getTitle());
                    }
                }
                
                // 设置处理人类型名称
                if (ObjUtil.isNotNull(vo.getProcessorType())) {
                    UserTypeEnum processorTypeEnum = UserTypeEnum.get(vo.getProcessorType());
                    if (ObjUtil.isNotNull(processorTypeEnum)) {
                        vo.setProcessorTypeName(processorTypeEnum.getMessage());
                    }
                }
            }
        }
        
        return paginatorVO;
    }
    
    /**
     * 填充单个报备VO的关联信息
     * 
     * @param vo 报备VO对象
     */
    private void enrichReportVO(CgmsCompanionOfflineOrderReportVO vo) {
        if (vo == null) {
            return;
        }
        
        // 填充服务人员信息
        if (ObjUtil.isNotNull(vo.getServiceUserId()) && !ObjUtil.equals(vo.getServiceUserId(), 0L)) {
            CgmsCompanionUser serviceUser = cgmsCompanionUserService.selectByPrimaryKey(vo.getServiceUserId());
            if (ObjUtil.isNotNull(serviceUser)) {
                vo.setServiceUserNickname(serviceUser.getNickName());
                vo.setServiceUserAvatar(serviceUser.getAvatar());
            }
        }
        
        // 填充商品信息
        if (ObjUtil.isNotNull(vo.getProductId()) && !ObjUtil.equals(vo.getProductId(), 0L)) {
            CgmsCompanionProduct product = cgmsCompanionProductService.selectByPrimaryKey(vo.getProductId());
            if (ObjUtil.isNotNull(product)) {
                vo.setProductName(product.getTitle());
            }
        }
        
        // 设置处理人类型名称
        if (ObjUtil.isNotNull(vo.getProcessorType())) {
            UserTypeEnum processorTypeEnum = UserTypeEnum.get(vo.getProcessorType());
            if (ObjUtil.isNotNull(processorTypeEnum)) {
                vo.setProcessorTypeName(processorTypeEnum.getMessage());
            }
        }
    }
} 